﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.IO;
using System.Threading;
using NotifyIcon = System.Windows.Forms.NotifyIcon;
using System.ServiceProcess;
using System.Windows.Input;

namespace AzureDriveUI
{
	public partial class App : Application
	{
		// Ensure only one instance of the app is running at a time.
		private Mutex mutex = new Mutex(true, "AzureDriveUI:031D16CA-694A-421F-B860-79ECDB38F19E");
		private NotifyIcon _notifyIcon = null;
		private ContextMenu _contextMenu = null;
		private bool _isRunning = false;

		protected override void OnStartup(StartupEventArgs e)
		{
			if (mutex.WaitOne(TimeSpan.Zero, true) == false)
			{
				this.Shutdown();

				return;
			}

			if (this.EnsureDokanServiceIsRunning() == false)
			{
				this.Shutdown();

				return;
			}

			_isRunning = true;

			// Notify Icon
			_notifyIcon = new System.Windows.Forms.NotifyIcon();
			_notifyIcon.Text = "Azure Virtual Directory";
			_notifyIcon.MouseClick += notifyIcon_MouseClick;
			_notifyIcon.DoubleClick += notifyIcon_DoubleClick;
			using (var iconStream = Application.GetResourceStream(new Uri("pack://application:,,,/Azure Drive UI;component/network-drive.ico")).Stream)
			{
				_notifyIcon.Icon = new System.Drawing.Icon(iconStream);
			}
			_notifyIcon.Visible = true;

			// Context Menu
			_contextMenu = new ContextMenu();
			_contextMenu.Items.Add(DriveMenuManager.GetMenu(_contextMenu));

			_contextMenu.Items.Add(new Separator());

			var optionsMenuItem = new MenuItem { Header = "Options", };
			_contextMenu.Items.Add(optionsMenuItem);
			optionsMenuItem.Click += optionsMenuItem_Click;

			_contextMenu.Items.Add(new Separator());

			var exitMenuItem = new MenuItem { Header = "Exit", };
			_contextMenu.Items.Add(exitMenuItem);
			exitMenuItem.Click += exitMenuItem_Click;

			try
			{
				DriveConfigurationManager.LoadConfiguration();
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "Load Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);

				this.Shutdown();

				return;
			}

			// Start services
			foreach (var item in DriveConfigurationManager.GetConfiguredDrives())
			{
				DriveServiceManager.StartService(item);
			}

			base.OnStartup(e);
		}

		protected override void OnExit(ExitEventArgs e)
		{
			if (mutex != null)
			{
				if (_isRunning)
				{
					mutex.ReleaseMutex();
					_isRunning = false;
				}

				mutex.Dispose();
				mutex = null;
			}

			if (_notifyIcon != null)
			{
				_notifyIcon.Visible = false;
				_notifyIcon.Dispose();
				_notifyIcon = null;
			}

			if (_contextMenu != null)
			{
				_contextMenu.IsOpen = false;
				_contextMenu = null;
			}

			base.OnExit(e);
		}

		private bool EnsureDokanServiceIsRunning()
		{
			var dokanMounterService = ServiceController.GetServices().FirstOrDefault(item => item.ServiceName == "DokanMounter");

			if (dokanMounterService == null)
			{
				MessageBox.Show("The DokanMounter must be installed and running to use this application. Go to 'http://azuredrive.codeplex.com/' and download the 'DokanInstall_0.6.0.exe (prerequisite)'.",
					"Dokan Not Installed", MessageBoxButton.OK, MessageBoxImage.Exclamation);

				return false;
			}

			if (dokanMounterService.Status != ServiceControllerStatus.Running)
			{
				try
				{
					dokanMounterService.Start();
				}
				catch (Exception ex)
				{
					MessageBox.Show(string.Format("The DokanMounter service is installed, but is not running. The following error occurred while trying to start the service.\n\n{0}", ex),
						"Dokan Service Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);

					return false;
				}
			}

			return true;
		}

		void notifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == System.Windows.Forms.MouseButtons.Right)
			{
				_contextMenu.IsOpen = true;
			}
		}

		void notifyIcon_DoubleClick(object sender, EventArgs e)
		{
			new OptionsWindow().ShowDialog();
		}

		void optionsMenuItem_Click(object sender, RoutedEventArgs e)
		{
			new OptionsWindow().ShowDialog();
		}

		void exitMenuItem_Click(object sender, RoutedEventArgs e)
		{
			this.Shutdown();
		}
	}
}
